package org.example.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.example.enums.KeyEnum;
import org.example.packets.bean.Group;
import org.example.packets.bean.User;
import org.tio.core.ChannelContext;
import org.tio.core.ChannelContextFilter;
import org.tio.core.Tio;
import org.tio.core.intf.Packet;
import org.tio.utils.lock.SetWithLock;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j
public class Im extends ImConfig {

    /**
     * 阻塞发送消息
     *
     * @param channelContext 上下文信息
     * @param packet         包信息
     */
    public static void bSend(ChannelContext channelContext, Packet packet) {
        if (channelContext == null || packet == null) {
            return;
        }
        Tio.bSend(channelContext, packet);
    }

    /**
     * 发送消息
     *
     * @param channelContext 上下文信息
     * @param packet         包信息
     */
    public static void send(ChannelContext channelContext, Packet packet) {
        if (channelContext == null || packet == null) {
            return;
        }
        Tio.send(channelContext, packet);
    }

    public static void sendToGroup(String groupId, Packet packet) {
        Tio.sendToGroup(get().tioConfig, groupId, packet);
    }

    public static void sendToGroup(String groupId, Packet packet, ChannelContextFilter filter) {
        Tio.sendToGroup(get().tioConfig, groupId, packet, filter);
    }

    public static void bSendToGroup(String groupId, Packet packet) {
        Tio.bSendToGroup(Im.get().tioConfig, groupId, packet);
    }

    /**
     * 绑定用户(如果配置了回调函数执行回调)
     *
     * @param channelContext IM通道上下文
     * @param user           绑定用户信息
     */
    public static void bindUser(ChannelContext channelContext, User user , List<Group> groups) {
        if (Objects.isNull(user) || StrUtil.isBlank(user.getId())) {
            log.error("user or userId is null");
            return;
        }
        String userId = user.getId();
        ImSessionContext imSessionContext = (ImSessionContext) channelContext.get(KeyEnum.IM_CHANNEL_SESSION_CONTEXT_KEY.getKey());
        Tio.bindUser(channelContext, userId);
        SetWithLock<ChannelContext> channelContextSetWithLock = Tio.getByUserid(Im.get().getTioConfig(), userId);
        ReentrantReadWriteLock.ReadLock lock = channelContextSetWithLock.getLock().readLock();
        try {
            lock.lock();
            if (CollUtil.isEmpty(channelContextSetWithLock.getObj())) {
                return;
            }
            imSessionContext.getImClientNode().setUser(user);
            imSessionContext.getImClientNode().setGroups(groups);
            ImConfig.userListener().onAfterBind(channelContext, user);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            lock.unlock();
        }
    }

}
